#ifndef _DAG_GRAPH_OPERATOR_H_
#define _DAG_GRAPH_OPERATOR_H_

#include "dag.h"

#include <memory>
#include <iostream>
#include <map>
#include <set>
#include <vector>

namespace dag {
	
	class DAG_LOCAL GraphOperator : public FrameOperator {

		GraphOperator& operator=(const GraphOperator& copy);

	public:
		GraphOperator(const GraphNode& graphNode, bool reverse = false);
		//GraphOperator(const GraphOperator& copy);
		virtual ~GraphOperator() throw();
		
		void operate(const Frame& input, Frame& output);
		static std::auto_ptr<FrameOperator> inflate(std::istream& binaryStream);
		
	protected:
		GraphOperator();		
	private:
		
		struct DAG_LOCAL FrameAndLink {
			Frame* frame;
			FrameLink* link;
		};
		void clear();
		
		const std::string& _frameOperatorID() const;
		void _serialize(std::ostream& binaryStream) const;
		
		void initForward(const GraphNode& graphNode);
		void initReverse(const GraphNode& graphNode);
		
		std::map<FrameOperator*, Frame*> m_OpInputs;
		std::map<FrameOperator*, Frame*> m_OpOutputs;
		std::map<FrameOperator*, std::vector<FrameAndLink>*> m_OpOutputLinks;
		std::set<FrameOperator*> m_FrameOps;
		std::set<Frame*> m_Frames;
		std::set<FrameLink*> m_Links;
		std::set<std::vector<FrameAndLink>*> m_LinkVectors;
		std::vector<FrameOperator*> m_OrderedFrameOps;
		
		static std::string m_OpId;
	};

}
#endif